#include <iostream>
#include <string>

// class House
// {
// public:
//     void Init()
//     {
//         BuildPart1();

//         for (int i = 0; i < 3; i++)
//             BuildPart2();

//         if (true /*...*/)
//             BuildPart3();
//     }

//     virtual void BuildPart1() = 0;
//     virtual void BuildPart2() = 0;
//     virtual void BuildPart3() = 0;
// };

// // 不同的House有不同的Build方法，但是总体构建过程是相同的
// class StoneHouse : public House
// {
//     void BuildPart1()
//     {
//         //...
//     }
//     void BuildPart2()
//     {
//         //...
//     }
//     void BuildPart3()
//     {
//         //...
//     }
// };

// class WoodHouse : public House
// {
//     void BuildPart1()
//     {
//         //...
//     }
//     void BuildPart2()
//     {
//         //...
//     }
//     void BuildPart3()
//     {
//         //...
//     }
// };

class House
{
public:
    void show()
    {
        printf("窗户%d个, 门%d个, 位于%s\n", window_, door_, location_.c_str());
    }

public:
    int window_;
    int door_;
    std::string location_;
};
// 不同的House有不同的Build方法，但是总体构建过程是相同的
class StoneHouse : public House
{
};

class WoodHouse : public House
{
};

class HouseBulider
{
public:
    HouseBulider(House *house) : house_(house) {}

    House *GetResult()
    {
        return house_;
    }

    virtual void BuildPart1() = 0;
    virtual void BuildPart2() = 0;
    virtual void BuildPart3() = 0;

protected:
    House *house_;
};

class StoneHouseBulider : public HouseBulider
{

public:
    StoneHouseBulider() : HouseBulider(new StoneHouse) {}

    // 具体House类实现具体的Build函数
    void BuildPart1()
    {
        house_->window_ = 5;
        house_->window_++;
    }
    void BuildPart2()
    {
        house_->door_ = house_->window_ / 2;
    }
    void BuildPart3()
    {
        house_->location_ = "Califonia";
    }
};

class WoodHouseBulider : public HouseBulider
{

public:
    WoodHouseBulider() : HouseBulider(new WoodHouse) {}

    void BuildPart1()
    {
        house_->window_ = 1;
    }
    void BuildPart2()
    {
        house_->door_ = 1;
    }
    void BuildPart3()
    {
        house_->location_ = "Xi'an";
    }
};

class Derictor
{
public:
    // 稳定的部分
    static void Construct(HouseBulider *bulider)
    {
        bulider->BuildPart1();

        for (int i = 0; i < 3; i++)
            bulider->BuildPart2();

        if (true /*...*/)
            bulider->BuildPart3();
    }
};

// 稳定的部分
House *ConstructHouse(HouseBulider *bulider)
{
    Derictor::Construct(bulider);
    return bulider->GetResult();
}

int main()
{
    House *sh = ConstructHouse(new StoneHouseBulider);
    sh->show();

    return 0;
}